package com.woniuxy.yoga.progress.service.impl;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.woniuxy.yoga.commons.core.statedata.ProductState;
import com.woniuxy.yoga.commons.core.util.DateUtil;
import com.woniuxy.yoga.progress.dao.model.Moncard;
import com.woniuxy.yoga.progress.dao.mapper.MoncardMapper;
import com.woniuxy.yoga.progress.model.exception.ProgressException;
import com.woniuxy.yoga.progress.model.exception.ProgressExceptionCode;
import com.woniuxy.yoga.progress.model.param.CreateMonCardParam;
import com.woniuxy.yoga.progress.service.MoncardService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoField;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 月卡流程表 服务实现类
 * </p>
 *
 * @author 韦用文,刘存益,郎腾霄
 * @since 2023年11月28日
 */
@Service
public class MoncardServiceImpl extends ServiceImpl<MoncardMapper, Moncard> implements MoncardService {

    @Autowired
    private MoncardMapper moncardMapper;

    /**
     * 创建月卡进度表
     * @param param 创建月卡进度表参数
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createMonCard(CreateMonCardParam param) throws Exception {
        QueryWrapper<Moncard> wrapper = new QueryWrapper<>();
        wrapper.eq("order_num",param.getOrderNum());
        Moncard moncard = moncardMapper.selectOne(wrapper);
        if (moncard!=null) throw new ProgressException(ProgressExceptionCode.PROGRESS_EXCEPTION_CODE_CARD_REPEAT);
        Moncard card = new Moncard();
        card.setOrderNum(param.getOrderNum());
        card.setUserId(param.getUserId());
        //设置月卡时间
        //设置开始时间为当前购买时间+1天
        String startTime = DateUtil.addDaysToString(param.getPayDate(), 1);
        //查询是否有未完成
        //若还有未完成月卡，则开始时间变为未完成卡的结束时间
        List<Moncard> unfinishMons = getUnfinishMon(param.getUserId());
        if (unfinishMons.size()>1){
            Moncard lastMons = null;
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            for (Moncard unfinishMon : unfinishMons) {
                String endTimeStr = unfinishMon.getMoncardEndTime();
                LocalDateTime end = LocalDateTime.parse(endTimeStr, formatter);
                if (lastMons==null||end.isAfter(LocalDateTime.parse(lastMons.getMoncardEndTime(),formatter))){
                    lastMons = unfinishMon;
                }
            }
            startTime = lastMons.getMoncardEndTime();
        }
        card.setMoncardStartTime(startTime);
        //设置结束时间为购买数量*30天
        Integer days = param.getOrderCount()*30;
        String endTime = DateUtil.addDaysToString(startTime, days);
        card.setMoncardEndTime(endTime);
        moncardMapper.insert(card);
        //设置定时任务，到期后完成月卡
        Map<String, Object> map = new HashMap<>();
        map.put("orderNum",param.getOrderNum());
        //转json字符串
        String orderNum = JSONUtil.toJsonStr(map);
        //设置定时任务
        String xxlLoginAPI="http://192.168.90.249:9999/xxl-job-admin/login";
        String xxlAddJobAPI="http://192.168.90.249:9999/xxl-job-admin/jobinfo/add";
        HashMap<String, Object> loginParam = new HashMap<>();
        loginParam.put("userName", "admin");
        loginParam.put("password", "123456");
        HttpResponse httpResponse = HttpRequest.post(xxlLoginAPI).form(loginParam).execute();
        if(httpResponse.getStatus()!=200) {
            throw new Exception("登录失败");
        }
        Map<String, Object> addTaskParam = new HashMap<>();
        addTaskParam.put("jobGroup", 7);
        LocalDateTime executeTime = DateUtil.StringToLocalDateTime(card.getMoncardEndTime());
        int year = executeTime.get(ChronoField.YEAR);
        int month = executeTime.get(ChronoField.MONTH_OF_YEAR);
        int day = executeTime.get(ChronoField.DAY_OF_MONTH);
        int hour=executeTime.get(ChronoField.HOUR_OF_DAY);
        int minute=executeTime.get(ChronoField.MINUTE_OF_HOUR);
        int second=executeTime.get(ChronoField.SECOND_OF_MINUTE);
        StringBuilder cron = new StringBuilder();
        cron.append(second);
        cron.append(" "+minute);
        cron.append(" "+hour);
        cron.append(" "+day);
        cron.append(" "+month);
        cron.append(" ?");
        cron.append(" "+year);
        addTaskParam.put("scheduleConf", cron.toString());
        addTaskParam.put("jobDesc", "月卡进度完成");
        addTaskParam.put("author", "Zachary");
        addTaskParam.put("executorHandler", "moncardExpire");
        addTaskParam.put("executorParam",orderNum);//订单编号
        addTaskParam.put("scheduleType", "CRON");
        addTaskParam.put("executorRouteStrategy", "FIRST");
        addTaskParam.put("executorBlockStrategy", "SERIAL_EXECUTION");
        addTaskParam.put("glueType", "BEAN");
        addTaskParam.put("misfireStrategy","DO_NOTHING");
        addTaskParam.put("executorTimeout", "0");
        addTaskParam.put("executorFailRetryCount","0");
        addTaskParam.put("triggerStatus", 1);
        HttpResponse response = HttpRequest.post(xxlAddJobAPI).form(addTaskParam).execute();
    }

    /**
     * 查询未完成月卡
     * @param userId userid
     * @return Moncard
     */
    @Override
    public List<Moncard> getUnfinishMon(Integer userId) {
        //创建查询
        QueryWrapper<Moncard> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id",userId);
        wrapper.le("moncard_end_time",LocalDateTime.now());
        List<Moncard> moncards = moncardMapper.selectList(wrapper);
        if (moncards.size()==0) throw new ProgressException(ProgressExceptionCode.PROGRESS_EXCEPTION_CODE_CARD_NOT_EXIST);
        return moncards;
    }
}
